package com.starmark.message.queue.producer.rabbitmq.service.imp;

import com.starmark.message.queue.producer.api.dto.MessageQueueDto;
import com.starmark.message.queue.producer.api.service.IMessageQueueProducerService;
import org.springframework.amqp.core.Queue;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * rabbitmq 消息队列
 *
 * @author starmark
 * @date 2020/5/10  上午10:41
 */
@Service
public class MessageQueueRabbitmqProducerServiceImpl implements IMessageQueueProducerService {
    private final ConfigurableApplicationContext applicationContext;

    private final List<IMessageQueueProducerService> messageQueueProducerServices;

    @Autowired
    public MessageQueueRabbitmqProducerServiceImpl(List<IMessageQueueProducerService> messageQueueProducerServiceList, ConfigurableApplicationContext applicationContext) {
        messageQueueProducerServices = messageQueueProducerServiceList.stream().filter(messageQueueConsumerService ->
                messageQueueConsumerService.support("rabbitmq")).collect(Collectors.toList());
        this.applicationContext = applicationContext;
    }

    //自动注入RabbitTemplate模板类
    @Autowired
    private RabbitTemplate rabbitTemplate;

    @Override
    public boolean produceMessage(MessageQueueDto messageQueueDto) {
       this.createQueue(messageQueueDto.getTopic());
        rabbitTemplate.convertAndSend(messageQueueDto.getTopic(), messageQueueDto.getMessage());

        return true;
    }

    @Override
    public boolean support(String producerType) {
        return Objects.equals(producerType, "rabbitmq");
    }

    /**
     * 创建rabbitmq 队例
     * @param topic　主题
     */
    private void createQueue(String topic) {
        if (!applicationContext.containsBean(topic)) {
            this.registerBean(topic  , topic);
        }
    }

    private void registerBean(String name, Object... args) {
        BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.genericBeanDefinition(Queue.class);
        if (args.length > 0) {
            for (Object arg : args) {
                beanDefinitionBuilder.addConstructorArgValue(arg);
            }
        }
        BeanDefinition beanDefinition = beanDefinitionBuilder.getRawBeanDefinition();

        BeanDefinitionRegistry beanFactory = (BeanDefinitionRegistry) applicationContext.getBeanFactory();
        beanFactory.registerBeanDefinition(name, beanDefinition);

    }
}
